import { defineStore } from 'pinia'
import { ref } from 'vue'
import { message } from 'ant-design-vue'
import { login as loginApi, refreshToken as refreshTokenApi, TokenInfo, LoginResponse } from '@/api/auth'
import { getUserById, updateUserInfo, changePassword } from '@/api/user'

// 自定义API响应类型
interface ApiResponse<T = any> {
  code: number
  data: T
  message: string
  [key: string]: any
}

// 导出基础用户信息接口
export interface BaseUserInfo {
  username: string
  gender: string
  phone: string
  email: string
  picture: string
  state: number
  context: string
  title: string | string[]
}

interface UserInfo extends BaseUserInfo {
  id: number
  birthday: string | null
  createTime: string | null
  updateTime: string | null
  role: string
  isAdmin?: boolean  // 添加可选的isAdmin属性
}

interface LoginData {
  username: string
  password: string
  rememberMe?: boolean
}

interface RegisterData {
  username: string
  password: string
  confirmPassword: string
  email: string
  phone?: string
}

interface PasswordData {
  oldPassword: string
  newPassword: string
  confirmPassword: string
}

export const useUserStore = defineStore('user', () => {
  const isLoggedIn = ref<boolean>(false)
  const userInfo = ref<UserInfo | null>(null)
  const accessToken = ref<string>('')
  const refreshTokenValue = ref<string>('')

  // 登录
  const login = async (loginData: LoginData): Promise<boolean> => {
    try {
      console.log('[登录] 开始登录流程')
      
      // 清理之前的登录状态，防止混合
      localStorage.removeItem('accessToken')
      localStorage.removeItem('refreshToken')
      localStorage.removeItem('userInfo')
      localStorage.removeItem('isLoggedIn')
      
      // 调用登录API
      const response = await loginApi(loginData)
      console.log('[登录] 获取到登录响应:', response)
      
      // 检查响应格式
      if (!response || !response.data) {
        console.error('[登录] 响应格式无效:', response)
        message.error('登录失败: 服务器响应格式错误')
        return false
      }
      
      // 从响应的data字段中提取令牌信息
      const tokenInfo = response.data
      console.log('[登录] 提取到令牌信息:', { 
        hasAccessToken: !!tokenInfo.accessToken,
        hasUserId: !!tokenInfo.userId,
        username: tokenInfo.username
      })
      
      // 检查令牌信息是否完整
      if (!tokenInfo || !tokenInfo.accessToken) {
        console.error('[登录] 令牌信息不完整:', tokenInfo)
        message.error('登录失败: 获取令牌失败')
        return false
      }
      
      // 保存令牌和用户信息
      accessToken.value = tokenInfo.accessToken
      refreshTokenValue.value = tokenInfo.refreshToken || ''
      
      // 确保用户ID是数字类型
      let userId: number
      if (typeof tokenInfo.userId === 'string') {
        userId = parseInt(tokenInfo.userId)
        if (isNaN(userId)) {
          console.error('[登录] 无效的用户ID:', tokenInfo.userId)
          message.error('登录失败: 用户信息无效')
          return false
        }
      } else {
        userId = tokenInfo.userId
      }
      
      // 设置初始用户信息
      userInfo.value = {
        id: userId,
        username: tokenInfo.username || '用户' + userId,
        gender: '',
        phone: '',
        email: '',
        picture: '',
        state: 1,
        context: '',
        title: '',
        birthday: null,
        createTime: null,
        updateTime: null,
        // 使用后端返回的角色，不再强制设置为超级管理员
        role: tokenInfo.role || 'ROLE_USER'
      }
      
      // 记录角色信息供调试使用
      console.log('[登录] 用户角色信息:', {
        role: tokenInfo.role,
        roles: tokenInfo.roles
      })
      
      isLoggedIn.value = true
      
      // 保存登录状态到本地存储
      localStorage.setItem('accessToken', accessToken.value)
      localStorage.setItem('refreshToken', refreshTokenValue.value)
      localStorage.setItem('userInfo', JSON.stringify(userInfo.value))
      localStorage.setItem('isLoggedIn', 'true')
      
      console.log('[登录] 已保存基本登录状态, 用户ID:', userId, '角色:', userInfo.value.role)
      
      // 获取完整用户信息
      try {
        console.log('[登录] 正在获取完整用户详情')
        await getUserDetail()
        console.log('[登录] 用户详情获取完成')
      } catch (error) {
        console.warn('[登录] 获取用户详情失败，但登录仍然有效:', error)
        // 登录是否有效取决于基本token，即使获取用户详情失败，登录也视为成功
      }
      
      // 根据用户角色判断权限层级
      const roleMessage = userInfo.value?.role?.includes('ADMIN') 
        ? '您拥有管理员权限，可访问管理后台' 
        : '';
      
      // 显示登录成功消息
      message.success(`登录成功${roleMessage ? ' - ' + roleMessage : ''}`);
      return true
    } catch (error: any) {
      // console.error('[登录] 失败:', error)
      message.error("账号或密码错误")
      // 检查错误是否已经在request拦截器中处理过
      if (!(error as any).isHandled) {
        // 只有未处理的错误才显示消息
        message.error(error.message || '登录失败')
      }
      
      return false
    }
  }

  // 刷新令牌
  const refresh = async (): Promise<boolean> => {
    try {
      if (!refreshTokenValue.value) {
        return false
      }
      
      const tokenInfo = await refreshTokenApi(refreshTokenValue.value)
      
      // 更新访问令牌
      accessToken.value = tokenInfo.accessToken
      localStorage.setItem('accessToken', accessToken.value)
      
      return true
    } catch (error) {
      console.error('刷新令牌失败:', error)
      // 刷新失败，清除登录状态
      logout()
      return false
    }
  }

  // 登出
  const logout = (): void => {
    console.log('[登出] 清除用户会话')
    isLoggedIn.value = false
    userInfo.value = null
    accessToken.value = ''
    refreshTokenValue.value = ''
    
    // 清除本地存储的所有登录状态
    localStorage.removeItem('isLoggedIn')
    localStorage.removeItem('userInfo')
    localStorage.removeItem('accessToken')
    localStorage.removeItem('refreshToken')
    
    console.log('[登出] 所有用户数据已清除')
    message.success('已退出登录')
  }

  // 注册
  const register = async (registerData: RegisterData): Promise<boolean> => {
    try {
      console.log('[注册] 开始注册流程')
      
      // 调用注册API
      const { register } = await import('@/api/user')
      const response = await register(registerData)
      
      // Axios包装了返回数据，实际数据在response.data中
      const responseData = response.data as ApiResponse
      
      // 检查响应状态码，后端返回的结构是 { code: 200, data: "注册成功", message: "操作成功" }
      if (responseData && responseData.code === 200) {
        console.log('[注册] 注册成功:', responseData)
        message.success(responseData.data || '注册成功，请登录')
        return true
      } else {
        console.error('[注册] 注册失败:', responseData)
        message.error(responseData?.message || '注册失败，请稍后再试')
        return false
      }
    } catch (error: any) {
      console.error('[注册] 出错:', error)
      
      // 检查错误是否已经在request拦截器中处理过
      if (!(error as any).isHandled) {
        // 只有未处理的错误才显示消息
        message.error(error.message || '注册失败，请稍后再试')
      }
      
      return false
    }
  }

  // 检查登录状态
  const checkLoginStatus = (): boolean => {
    const storedLoginStatus = localStorage.getItem('isLoggedIn')
    const storedUserInfo = localStorage.getItem('userInfo')
    const storedAccessToken = localStorage.getItem('accessToken')
    const storedRefreshToken = localStorage.getItem('refreshToken')
    
    if (storedLoginStatus === 'true' && storedUserInfo && storedAccessToken) {
      isLoggedIn.value = true
      userInfo.value = JSON.parse(storedUserInfo)
      accessToken.value = storedAccessToken
      refreshTokenValue.value = storedRefreshToken || ''
      return true
    }
    return false
  }

  // 更新用户信息
  const updateUser = async (updateData: Partial<BaseUserInfo>): Promise<boolean> => {
    try {
      // 确保有用户 ID
      if (!userInfo.value || !userInfo.value.id) {
        throw new Error('用户未登录')
      }
      
      // 添加用户 ID 到更新数据
      const data = {
        ...updateData,
        id: userInfo.value.id
      }
      
      // 确保 title 字段是字符串
      if (data.title && Array.isArray(data.title)) {
        data.title = JSON.stringify(data.title)
      }
      
      // 调用 API
      const response = await updateUserInfo(data)
      
      if (response) {
        // 更新本地存储的用户信息
        userInfo.value = {
          ...userInfo.value,
          ...updateData
        }
        // 更新本地存储
        localStorage.setItem('userInfo', JSON.stringify(userInfo.value))
        return true
      } else {
        throw new Error('更新失败')
      }
    } catch (error) {
      console.error('更新用户信息失败:', error)
      throw error
    }
  }

  // 修改密码
  const updatePassword = async (passwordData: PasswordData): Promise<boolean> => {
    try {
      if (!userInfo.value?.id) {
        throw new Error('用户未登录')
      }

      const res = await changePassword(passwordData)
      if (res) {
        message.success('密码修改成功')
        return true
      }
      return false
    } catch (error: any) {
      console.error('修改密码失败:', error)
      message.error(error.message || '修改失败')
      return false
    }
  }

  // 获取用户详情
  const getUserDetail = async (): Promise<boolean> => {
    try {
      // 确保有用户 ID
      if (!userInfo.value || !userInfo.value.id) {
        console.warn('[获取用户详情] 用户未登录或ID不存在')
        return false
      }
      
      // 确保ID是数字类型 - 此时我们确认userInfo.value不为null
      const currentUserInfo = userInfo.value // 缓存引用，避免多次空检查
      let userId: number
      
      if (typeof currentUserInfo.id === 'string') {
        userId = parseInt(currentUserInfo.id)
        if (isNaN(userId) || userId <= 0) {
          console.error('[获取用户详情] 无效的用户ID:', currentUserInfo.id)
          return false
        }
      } else {
        userId = currentUserInfo.id
      }
      
      console.log('[获取用户详情] 尝试获取用户ID:', userId)
      
      // 添加重试逻辑
      let attempts = 0
      const maxAttempts = 2
      let success = false
      let response = null
      
      while (!success && attempts <= maxAttempts) {
        try {
          attempts++
          console.log(`[获取用户详情] 第${attempts}次尝试`)
          
          // 调用API获取用户信息
          response = await getUserById(userId)
          
          if (response && response.data) {
            success = true
            console.log('[获取用户详情] 成功获取数据')
          } else {
            console.warn(`[获取用户详情] 第${attempts}次尝试返回无效数据`)
            if (attempts < maxAttempts) {
              await new Promise(resolve => setTimeout(resolve, 1000))
            }
          }
        } catch (error) {
          console.error(`[获取用户详情] 第${attempts}次尝试失败:`, error)
          if (attempts < maxAttempts) {
            console.log('[获取用户详情] 将在1秒后重试')
            await new Promise(resolve => setTimeout(resolve, 1000))
          }
        }
      }
      
      if (!success) {
        console.error('[获取用户详情] 多次尝试后仍然失败')
        return false
      }
      
      // 处理响应数据
      if (response && response.data) {
        console.log('[获取用户详情] 处理返回的用户数据')
        
        // 数据类型转换
        const userData = { ...response.data }
        
        // 保存当前用户角色（确保保留超级管理员权限）
        const currentRole = userInfo.value?.role || 'ROLE_USER'
        
        // 处理ID字段
        if (typeof userData.id === 'string') {
          userData.id = parseInt(userData.id)
          console.log('[获取用户详情] 将ID从字符串转为数字:', userData.id)
        }
        
        // 处理title字段
        if (typeof userData.title === 'string' && userData.title.startsWith('[') && userData.title.endsWith(']')) {
          try {
            userData.title = JSON.parse(userData.title)
            console.log('[获取用户详情] 已将title从JSON字符串转为数组')
          } catch (e) {
            console.warn('[获取用户详情] 解析title字段失败，保留原始格式')
          }
        }
        
        // 合并数据，确保不丢失本地已有的数据
        userInfo.value = {
          ...userInfo.value,
          ...userData,
          // 使用后端返回的角色，如果没有则保持当前角色
          role: userData.role || currentRole
        }
        
        // 记录角色信息供调试使用
        if (userInfo.value) {
          console.log('[获取用户详情] 用户角色信息:', {
            role: userInfo.value.role,
            roles: userData.roles
          });
        }
        
        // 再次确保ID字段是数字且有效
        if (userInfo.value && typeof userInfo.value.id === 'string') {
          userInfo.value.id = parseInt(userInfo.value.id);
        }
        
        // 更新本地存储
        if (userInfo.value) {
          localStorage.setItem('userInfo', JSON.stringify(userInfo.value));
          console.log('[获取用户详情] 已更新本地存储的用户信息');
        }
        
        return true
      } else {
        console.warn('[获取用户详情] 没有获取到有效数据')
        return false
      }
    } catch (error) {
      console.error('[获取用户详情] 异常:', error)
      return false
    }
  }

  return {
    isLoggedIn,
    userInfo,
    accessToken,
    refreshTokenValue,
    login,
    refresh,
    logout,
    register,
    checkLoginStatus,
    updateUser,
    updatePassword,
    getUserDetail
  }
}) 